# -*- coding: utf-8 -*-
from core.serializers import CustomModelSerializer
from core.relations import BaseNameWritableRelatedField, UserNameWritableRelatedField
from rest_framework import serializers
from collections import defaultdict
from apps.tms.models import Job, JobLog, Bug
from apps.pms.requirement.serializers import ListRequirementSerializer
from apps.tms.testcase.serializers import TestCaseSerializer
from apps.tms.bug.serializers import BugSerializer
from apps.sys.models import DictData
from .models import TestReport


class ListTestReportSerializer(CustomModelSerializer):
    """
    测试报告列表-序列化器
    """

    product_name = serializers.CharField(read_only=True, source="product.name")

    class Meta:
        model = TestReport
        fields = "__all__"
        read_only_fields = ["id"]


class TestReportSerializer(CustomModelSerializer):
    """
    测试报告详情-序列化器
    """

    product = BaseNameWritableRelatedField()
    owner = UserNameWritableRelatedField()
    testplan = BaseNameWritableRelatedField()
    participants = UserNameWritableRelatedField(many=True)

    reqs_count = serializers.SerializerMethodField()
    cases_count = serializers.SerializerMethodField()
    bugs_count = serializers.SerializerMethodField()
    bug_rate = serializers.SerializerMethodField()
    reqs_coverage = serializers.SerializerMethodField()

    cases_status = serializers.SerializerMethodField()
    cases_type = serializers.SerializerMethodField()
    cases_module = serializers.SerializerMethodField()
    cases_executor = serializers.SerializerMethodField()
    bugs_gravity = serializers.SerializerMethodField()
    bugs_type = serializers.SerializerMethodField()
    bugs_status = serializers.SerializerMethodField()
    bugs_resolved_type = serializers.SerializerMethodField()
    bugs_module = serializers.SerializerMethodField()
    bugs_creator = serializers.SerializerMethodField()

    def get_reqs_count(self, instance):
        return len(instance.testplan.requirements.all())

    def get_cases_count(self, instance):
        return len(instance.testplan.testcases.all())

    def get_bugs_count(self, instance):
        related_bugs = set()
        for related_case in instance.testplan.testcases.all():
            for related_bug in related_case.bug_set.filter(
                version=instance.testplan.version
            ):
                related_bugs.add(related_bug)
        return len(related_bugs)

    def get_bug_rate(self, instance):
        related_bugs = set()
        testcases = instance.testplan.testcases.all()
        for related_case in instance.testplan.testcases.iterator():
            for related_bug in related_case.bug_set.filter(
                version=instance.testplan.version
            ):
                related_bugs.add(related_bug)
        return "{}%".format(
            len(related_bugs) / len(testcases) * 100 if (len(testcases) > 0) else 0
        )

    def get_reqs_coverage(self, instance):
        total_cases = 0
        requirements = instance.testplan.requirements.all()
        for requirement in instance.testplan.requirements.iterator():
            if len(requirement.testcase_set.all()) > 0:
                total_cases += 1
        return "{}%".format(
            total_cases / len(requirements) * 100 if (len(requirements) > 0) else 0
        )

    def get_cases_status(self, instance):
        status_counts = defaultdict(int)

        for testcase in instance.testplan.testcases.iterator():
            dict_map = DictData.objects.filter(
                type="tms_job_status", value=testcase.status
            ).first()
            status_name = dict_map.label if dict_map else None

            # 如果状态名存在，则增加其计数
            if status_name:
                status_counts[status_name] += 1

        # 将 defaultdict 转换为普通字典
        return [{"value": count, "name": name} for name, count in status_counts.items()]

    def get_cases_type(self, instance):
        type_counts = defaultdict(int)

        for testcase in instance.testplan.testcases.iterator():
            dict_map = DictData.objects.filter(
                type="tms_tc_type", value=testcase.type
            ).first()
            type_name = dict_map.label if dict_map else None

            # 如果状态名存在，则增加其计数
            if type_name:
                type_counts[type_name] += 1

        # 将 defaultdict 转换为普通字典
        return [{"value": count, "name": name} for name, count in type_counts.items()]

    def get_cases_module(self, instance):
        module_counts = defaultdict(int)

        for testcase in instance.testplan.testcases.iterator():
            module_name = testcase.module.name

            # 如果状态名存在，则增加其计数
            if module_name:
                module_counts[module_name] += 1

        # 将 defaultdict 转换为普通字典
        return [{"value": count, "name": name} for name, count in module_counts.items()]

    def get_cases_executor(self, instance):
        executor_counts = defaultdict(int)

        for testcase in instance.testplan.testcases.iterator():
            # jobs = Job.objects.filter(testplan=instance.testplan)
            joblog = JobLog.objects.filter(number=testcase.number).last()
            if joblog:
                executor_name = joblog.executor
                if executor_name:
                    executor_counts[executor_name] += 1

        # 将 defaultdict 转换为普通字典
        return [
            {"value": count, "name": name} for name, count in executor_counts.items()
        ]

    def get_bugs_gravity(self, instance):
        gravity_counts = defaultdict(int)

        for testcase in instance.testplan.testcases.iterator():
            bug = Bug.objects.filter(tcs=testcase).last()
            if bug:
                dict_map = DictData.objects.filter(
                    type="sys_gravity_level", value=bug.gravity
                ).first()
                gravity_name = dict_map.label if dict_map else None

                # 如果状态名存在，则增加其计数
                if gravity_name:
                    gravity_counts[gravity_name] += 1

        # 将 defaultdict 转换为普通字典
        return [
            {"value": count, "name": name} for name, count in gravity_counts.items()
        ]

    def get_bugs_type(self, instance):
        type_counts = defaultdict(int)

        for testcase in instance.testplan.testcases.iterator():
            bug = Bug.objects.filter(tcs=testcase).last()
            if bug:
                dict_map = DictData.objects.filter(
                    type="tms_bug_type", value=bug.type
                ).first()
                type_name = dict_map.label if dict_map else None

                # 如果状态名存在，则增加其计数
                if type_name:
                    type_counts[type_name] += 1

        # 将 defaultdict 转换为普通字典
        return [{"value": count, "name": name} for name, count in type_counts.items()]

    def get_bugs_status(self, instance):
        status_counts = defaultdict(int)

        for testcase in instance.testplan.testcases.iterator():
            bug = Bug.objects.filter(tcs=testcase).last()
            if bug:
                dict_map = DictData.objects.filter(
                    type="tms_bug_status", value=bug.status
                ).first()
                status_name = dict_map.label if dict_map else None

                # 如果状态名存在，则增加其计数
                if status_name:
                    status_counts[status_name] += 1

        # 将 defaultdict 转换为普通字典
        return [{"value": count, "name": name} for name, count in status_counts.items()]

    def get_bugs_resolved_type(self, instance):
        resolved_type_counts = defaultdict(int)

        for testcase in instance.testplan.testcases.iterator():
            bug = Bug.objects.filter(tcs=testcase).last()
            if bug:
                dict_map = DictData.objects.filter(
                    type="tms_bug_resolved_type", value=bug.resolved_type
                ).first()
                resolved_type_name = dict_map.label if dict_map else None

                # 如果状态名存在，则增加其计数
                if resolved_type_name:
                    resolved_type_counts[resolved_type_name] += 1

        # 将 defaultdict 转换为普通字典
        return [
            {"value": count, "name": name}
            for name, count in resolved_type_counts.items()
        ]

    def get_bugs_module(self, instance):
        module_counts = defaultdict(int)

        for testcase in instance.testplan.testcases.iterator():
            bug = Bug.objects.filter(tcs=testcase).last()
            module_name = bug.module.name if bug else None
            # 如果状态名存在，则增加其计数
            if module_name:
                module_counts[module_name] += 1

        # 将 defaultdict 转换为普通字典
        return [{"value": count, "name": name} for name, count in module_counts.items()]

    def get_bugs_creator(self, instance):
        creator_counts = defaultdict(int)

        for testcase in instance.testplan.testcases.iterator():
            bug = Bug.objects.filter(tcs=testcase).last()
            if bug:
                if bug.creator:
                    creator_name = bug.creator.name
                    creator_counts[creator_name] += 1

        # 将 defaultdict 转换为普通字典
        return [
            {"value": count, "name": name} for name, count in creator_counts.items()
        ]

    class Meta:
        model = TestReport
        fields = "__all__"
        read_only_fields = ["id"]
